import sys,os,inspect,ctypes,getpass,re
import psutil,subprocess,traceback,tkinter,signal,tkinter.messagebox

username = getpass.getuser()
# 创建临时文件夹
make_dir = 'C:\\Users\\' + username + '\\Documents\\DA_Tools\\'
# 工具全局监控异常日志
traceback_log = make_dir + 'traceback.log'


def adb_tools_log(fun_name):
    # 捕获异常装饰器
    def log(*args, **kwargs):
        try:
            fun_name(*args, **kwargs)
        except Exception:
            traceback.print_exc()
            # 记录异常
            with open(traceback_log,'w') as fp:
                fp.write(str(traceback.format_exc()))
            content = '''
            功能发生异常，请联系开发者596044192@qq.com进行修复
            异常日志已保存在{}
            点击“确定”后会自动关闭本工具，请重新启动使用即可！
            '''
            tkinter.messagebox.showinfo('异常',content.format(traceback_log))
            # 强制结束python.exe程序
            # execute_cmd('taskkill /F /IM %s ' % 'python.exe /T')
            pid = os.getpid()  # 获取当前程序pid
            pid_name = psutil.Process(pid).name()  # 根据pid获取当前程序名
            # 强制结束当前程序
            execute_cmd('taskkill /F /IM %s ' % pid_name + ' /T')
            pid = os.getpid()
            os.kill(pid,signal.SIGINT)
            sys.exit()
    return log


def resource_path(relative_path):
    """生成资源文件目录访问路径"""
    if getattr(sys, 'frozen', False):
        base_path = sys._MEIPASS
    else:
        base_path = os.path.abspath('.')
    return os.path.join(base_path, relative_path)


def _async_raise(tid, exctype):
    """Raises an exception in the threads with id tid"""
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # """if it returns a number greater than one, you're in trouble,
        # and you should call it again with exc=NULL to revert the effect"""
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")


def stop_thread(thread):
    # 终止进程
    _async_raise(thread.ident, SystemExit)


def get_pid_name():
    # 获取进程名
    Processes = []
    pids = psutil.pids()
    try:
        for pid in pids:
            pid_names = psutil.Process(pid).name()
            # 获取所有进程名称并添加到列表中
            Processes.append(pid_names)
    except psutil.NoSuchProcess:
        # print('不存在该进程，继续执行！')
        pass
    return Processes


def execute_cmd(cmd):
    proc = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,stdin=subprocess.PIPE)
    proc.stdin.close()
    proc.wait()
    try:
        result = proc.stdout.read().decode('gbk')  # 注意你电脑cmd的输出编码（中文是gbk）
    except UnicodeDecodeError:
        result = proc.stdout.read().decode('utf-8')  # 适用于截图录屏功能，针对截图录屏文件名中文编码报错的异常处理
    proc.stdout.close()
    return result
